package com.genymobile.scrcpy.five;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;

import com.genymobile.scrcpy.five.cmd.FiveMotionEventCmd;
import com.genymobile.scrcpy.five.connection.ConnectionClientForRecord;
import com.genymobile.scrcpy.five.connection.ConnectionConfig;
import com.genymobile.scrcpy.five.connection.HttpServer;
import com.genymobile.scrcpy.five.inject.FiveInjector;

import java.io.IOException;

import fi.iki.elonen.NanoHTTPD;

/**
 * 普通投屏时，启动这个server，处理来自fifo的命令，即windows端发送来的命令，比如三指左滑
 */
public class NoramlScrcpyCmdServer {
    private final String mTag;
    private final Handler mHandler;
    public NoramlScrcpyCmdServer(int displayId) {
        mTag = NoramlScrcpyCmdServer.class.getSimpleName() + displayId;
        this.displayId = displayId;
        HandlerThread handlerThread = new HandlerThread("cmd handler");
        handlerThread.start();
        mHandler = new Handler(handlerThread.getLooper());
    }
    private int displayId = -1;
    private final FiveInjector injector = new FiveInjector();
    private void injectTrippleFingerSwipe(int dspId, final int fromx, final int fromy, final int tox, final int toy) {
        if (GlobalConfig.LOG_ENABLE) Log.d(mTag, "injectTrippleFingerSwipe() begin() ==>");
        int nowX = fromx;
        int derta = (tox - fromx) / 20;
        final int direction = derta >= 0 ? 1 : -1;
        int xStep = 10;

        int i=0;
        injectAndRecord(MotionEvent.ACTION_DOWN, i++, nowX, fromy, dspId);
        injectAndRecord(MotionEvent.ACTION_DOWN, i++, nowX, fromy + 100, dspId);
        injectAndRecord(MotionEvent.ACTION_DOWN, i++, nowX, fromy + 200, dspId);
        while ( ((nowX - tox) * direction) < 0 ) {
            xStep += 1;
            nowX += (xStep*direction);
            Log.d(mTag, "nowX=" + nowX);
            {
                i=0;
                injectAndRecord(MotionEvent.ACTION_MOVE, i++, nowX, fromy, dspId);
                injectAndRecord(MotionEvent.ACTION_MOVE, i++, nowX, fromy + 100, dspId);
                injectAndRecord(MotionEvent.ACTION_MOVE, i++, nowX, fromy + 200, dspId);
            }
            try {
                Thread.sleep(20);
            } catch (Exception ignored) {}
        }
        i=0;
        injectAndRecord(MotionEvent.ACTION_UP, i++, nowX, fromy, dspId);
        injectAndRecord(MotionEvent.ACTION_UP, i++, nowX, fromy + 100, dspId);
        injectAndRecord(MotionEvent.ACTION_UP, i++, nowX, fromy + 200, dspId);
        if (GlobalConfig.LOG_ENABLE) Log.d(mTag, "injectTrippleFingerSwipe() end()");
    }

    FiveMotionEventCmd cmd = new FiveMotionEventCmd();
    private void injectAndRecord(int action, int fingerIndex, int x, int y, int dspId) {
        int pressure = action == MotionEvent.ACTION_UP ? 0 : 1;
        injector.injectTouch(action, fingerIndex, x, y, pressure, 0, 0, dspId);
        cmd.timestampMs = SystemClock.elapsedRealtime();
        cmd.action = action;
        cmd.fingerId = fingerIndex;
        cmd.displayId = dspId;
        cmd.x = x;
        cmd.y = y;
        cmd.pressure = pressure;
        ConnectionClientForRecord.send(cmd.toString());
    }

    void tryHandleCmd(String line) {
        if (GlobalConfig.LOG_ENABLE) Log.d(mTag, "tryHandleCmd() " + line);
        if ("triggleSwipeToLeft".equalsIgnoreCase(line)) {
            // 三指左滑
            LogUtils.log(mTag, "三指左滑");
            mHandler.post(() -> injectTrippleFingerSwipe(4, 1000, 400, 200, 400));
        } else if ("triggleSwipeToRight".equalsIgnoreCase(line)) {
            // 三指右滑
            LogUtils.log(mTag, "三指右滑");
            mHandler.post(() -> injectTrippleFingerSwipe(0, 200, 400, 1000, 400));
        }
    }

    /**
     * scrcpy屏幕，接收来自windows端的cmd
     */
    public void startCmdServer() {
//        new ConnectionServer("cmdServer", ConnectionConfig.PORT_FOR_CMD_SERVER, this::tryHandleCmd).start();
        HttpServer server = new HttpServer(ConnectionConfig.PORT_FOR_CMD_HTTP_SERVER, this::tryHandleCmd);
        try {
            server.start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
